package com.haircut.sys.service.user.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haircut.project.model.group.ProjectGroup;
import com.haircut.project.service.group.IProjectGroupService;
import com.haircut.sys.dao.role.SysRoleMapper;
import com.haircut.sys.dao.user.SysUserMapper;
import com.haircut.sys.model.dept.SysDept;
import com.haircut.sys.model.user.SysUser;
import com.haircut.sys.service.dept.IDeptService;
import com.haircut.sys.service.permission.IPermissionService;
import com.haircut.sys.service.role.IRoleService;
import com.haircut.sys.service.user.IUserService;
import com.haircut.sys.utils.PageUtils;
import com.haircut.sys.utils.user.SecurityUtils;
import com.haircut.sys.vo.DataSttsVo;
import com.haircut.sys.vo.dept.DeptSimpleVo;
import com.haircut.sys.vo.role.RoleSimpleVo;
import com.haircut.sys.vo.user.*;
import com.modular.constant.BaseCodeDesc;
import com.modular.constant.NumberConstant;
import com.modular.enums.DataSource;
import com.modular.enums.DataStts;
import com.modular.exception.ModularException;
import com.modular.result.PageResult;
import com.modular.utils.DBUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IDeptService deptService;
    @Autowired
    private IPermissionService permissionService;
    @Autowired
    private IProjectGroupService projectGroupService;


    @Autowired
    @Qualifier("modularSnowflake")
    private Snowflake snowflake;
    /**
     * 新增或修改用户信息
     * @param userVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(UserAddVo userVo)
    {
        String userId = SecurityUtils.getUserId();
        if(hasSameUserccount(userVo.getId(),userVo.getUserAccount())){
            throw  new ModularException(BaseCodeDesc.DEFATUL_MSG,"登录用户重复，不能新增");
        }
        SysUser user = new SysUser();
        BeanUtils.copyProperties(userVo,user);
        user.setCreateUserId(userId);
        user.setCreateDate(DateUtil.date());
        user.setModifyDate(user.getCreateDate());
        user.setModifyUserId(userId);
        user.setUserwd(SecureUtil.md5(userVo.getUserwd()));
        user.setDataStts(DataStts.ENABLED.getCode());
        user.setDataSource(DataSource.USER.getCode());
        user.setTechnicianRate(userVo.getTechnicianRate());
        user.setId(snowflake.nextIdStr());
        userMapper.insert(user);
    }
    /**
     * 新增或修改用户信息
     * @param userVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(UserVo userVo)
    {
        SysUser user = userMapper.selectById(userVo.getId());
        if(ObjectUtil.isNull(user)){
            throw  new ModularException(BaseCodeDesc.DEFATUL_MSG,"用户id错误");
        }
        String userId = SecurityUtils.getUserId();
        if(hasSameUserccount(userVo.getId(),userVo.getUserAccount())){
            throw  new ModularException(BaseCodeDesc.DEFATUL_MSG,"登录用户重复，不能新增");
        }
        LambdaUpdateWrapper<SysUser> modify = Wrappers.lambdaUpdate();
        modify.set(SysUser::getModifyDate,DateUtil.date()).set(SysUser::getModifyUserId,userId);
        if(StrUtil.isNotBlank(userVo.getUserMobile())){
            modify.set(SysUser::getUserMobile,userVo.getUserMobile());
        }
        if(StrUtil.isNotBlank(userVo.getUserAccount())){
            modify.set(SysUser::getUserAccount,userVo.getUserAccount());
        }
        if(StrUtil.isNotBlank(userVo.getRealName())){
            modify.set(SysUser::getRealName,userVo.getRealName());
        }
        if(StrUtil.isNotBlank(userVo.getRoleId())){
            modify.set(SysUser::getRoleId,userVo.getRoleId());
        }
        if(StrUtil.isNotBlank(userVo.getDeptId())){
            modify.set(SysUser::getDeptId,userVo.getDeptId());
        }
        if(ObjectUtil.isNotNull(userVo.getSex())){
            modify.set(SysUser::getSex,userVo.getSex());
        }
        if(ObjectUtil.isNotNull(userVo.getMaritalStatus())){
            modify.set(SysUser::getMaritalStatus,userVo.getMaritalStatus());
        }
        if(ObjectUtil.isNull(userVo.getTechnicianRate())){
            modify.set(SysUser::getTechnicianRate,null);
        }else{
            modify.set(SysUser::getTechnicianRate,userVo.getTechnicianRate());
        }

//        if(ObjectUtil.isNotNull(userVo.getUserwd())){
//            modify.set(SysUser::getUserwd,SecureUtil.md5(userVo.getUserwd()));
//        }
        modify.eq(SysUser::getId,userVo.getId());
        userMapper.update(modify);

    }

    /**
     * 修改当前登录的用户
     * @param userVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyProfile(UserOnlyVo userVo)
    {
        String userId = SecurityUtils.getUserId();
        LambdaUpdateWrapper<SysUser> modify = Wrappers.lambdaUpdate();
        modify.set(SysUser::getModifyDate,DateUtil.date()).set(SysUser::getModifyUserId,userId);
        modify.set(SysUser::getUserMobile,userVo.getUserMobile());
        modify.set(SysUser::getRealName,userVo.getRealName());
        modify.set(SysUser::getSex,userVo.getSex());
        modify.eq(SysUser::getId,userId);
        userMapper.update(modify);
    }

    /**
     * 修改当前登录的用户
     * @param userVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePwd(UpdatePwdVo userVo)
    {
        String userId = SecurityUtils.getUserId();
        SysUser user = userMapper.selectById(userId);
        if(ObjectUtil.notEqual(user.getUserwd(),SecureUtil.md5(userVo.getOldPassword()))){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"旧密码错误");
        }
        LambdaUpdateWrapper<SysUser> modify = Wrappers.lambdaUpdate();
        modify.set(SysUser::getModifyDate,DateUtil.date()).set(SysUser::getModifyUserId,userId);
        modify.set(SysUser::getUserwd,SecureUtil.md5(userVo.getNewPassword()));
        modify.eq(SysUser::getId,userId);
        userMapper.update(modify);
    }

    /**
     * 用户密码
     * @param userVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPwd(UserPwdVo userVo)
    {
        SysUser user = userMapper.selectById(userVo.getId());
        if(ObjectUtil.isNull(user)){
            throw  new ModularException(BaseCodeDesc.DEFATUL_MSG,"用户id错误");
        }
        String userId = SecurityUtils.getUserId();
        LambdaUpdateWrapper<SysUser> modify = Wrappers.lambdaUpdate();
        modify.set(SysUser::getModifyDate,DateUtil.date()).set(SysUser::getModifyUserId,userId);
        if(ObjectUtil.isNotNull(userVo.getUserwd())){
            modify.set(SysUser::getUserwd,SecureUtil.md5(userVo.getUserwd()));
        }
        modify.eq(SysUser::getId,userVo.getId());
        userMapper.update(modify);
    }

    /**
     * 修改状态
     * @param dataSttsVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modifyDataStts(DataSttsVo dataSttsVo)
    {
        SysUser user = userMapper.selectById(dataSttsVo.getId());
        if(ObjectUtil.isNull(user)){
            throw  new ModularException(BaseCodeDesc.DEFATUL_MSG,"用户id错误");
        }
        String userId = SecurityUtils.getUserId();
        LambdaUpdateWrapper<SysUser> modify = Wrappers.lambdaUpdate();
        modify.set(SysUser::getModifyDate,DateUtil.date()).set(SysUser::getModifyUserId,userId);
        modify.set(SysUser::getDataStts,dataSttsVo.getDataStts());
        modify.eq(SysUser::getId,dataSttsVo.getId());
        userMapper.update(modify);
    }

    /**
     * 查询用户详情
     * @param userId
     * @return
     */
    @Override
    public UserVo findDetail(String userId){
        SysUser user = userMapper.selectById(userId);
        if(ObjectUtil.isNull(user)){
            throw  new ModularException(BaseCodeDesc.DEFATUL_MSG,"用户id错误");
        }
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo);
        return userVo;
    }

    /**
     * 分页查询用户信息
     * @param reqVo
     * @return
     */
    @Override
    public PageResult<UserResVo> findPage(UserReqVo reqVo)
    {
        reqVo.setUserAccount(DBUtils.escapeQuryLikeParam(reqVo.getUserAccount()));
        reqVo.setUserMobile(DBUtils.escapeQuryLikeParam(reqVo.getUserMobile()));
        if(StrUtil.isNotBlank(reqVo.getDeptId())){
            SysDept dept = deptService.findById(reqVo.getDeptId());
            reqVo.setHierarchy(DBUtils.escapeQuryRightLikeParam(dept.getHierarchy()));
        }
        reqVo.setDataScopeList(permissionService.findPermissionSqlList("t.id","t.dept_id"));

        IPage<?> pageReq = Page.of(reqVo.getPageNum(),reqVo.getPageSize());
        Page<UserResVo> userPage = userMapper.findPage(pageReq,reqVo);
        if(ObjectUtil.isNull(userPage) || CollUtil.isEmpty(userPage.getRecords())){
            return PageUtils.cover(reqVo);
        }
        List<String> roleIdList = userPage.getRecords().stream().map(UserResVo::getRoleId).distinct().toList();
        List<String> deptIdList = userPage.getRecords().stream().map(UserResVo::getDeptId).distinct().toList();
        Map<String, RoleSimpleVo> roleMap = roleService.findRoleMapByRoleIdList(roleIdList);
        Map<String, DeptSimpleVo> deptMap = deptService.findDeptMapByDeptIdList(deptIdList);
        for(UserResVo user:userPage.getRecords()){
            user.setRoleName(roleMap.get(user.getRoleId()).getRoleName());
            user.setDeptName(deptMap.get(user.getDeptId()).getDeptName());
        }

        return PageUtils.cover(userPage);
    }

    /**
     * 判断登录用户是否重复
     * @param userId
     * @param userAccount
     * @return
     */
    private Boolean hasSameUserccount(String userId,String userAccount){
        LambdaQueryWrapper<SysUser> query = Wrappers.lambdaQuery();
        query.eq(SysUser::getUserAccount,userAccount);
        if(StrUtil.isNotBlank(userId)){
            query.ne(SysUser::getId,userId);
        }
        Long count = userMapper.selectCount(query);
        return ObjectUtil.isEmpty(count) || ObjectUtil.equal(count, NumberConstant.ZERO);
    }

    /**
     * 根据账号查询用户信息
     * @param account
     * @return
     */
    @Override
    public SysUser findByAccount(String account)
    {
        LambdaQueryWrapper<SysUser> query = Wrappers.lambdaQuery();
        query.eq(SysUser::getUserAccount,account);
        List<SysUser> userList = userMapper.selectList(query);
        if(CollUtil.isEmpty(userList)){
            throw new ModularException(BaseCodeDesc.DEFATUL_MSG,"用户账号错误");
        }
        return userList.stream().findFirst().get();
    }

    /**
     * 获得用户详情
     * @return
     */
    @Override
    public ApiUserVo getUserDetail()
    {
       SysUser user =   userMapper.selectById(SecurityUtils.getUserId());
        ApiUserVo userVo = new ApiUserVo();
        BeanUtils.copyProperties(user,userVo);
        return userVo;
    }



}
